﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Workflow
//  File name:	AssignmentInstance.cs
//  Developer:	Solomatov Igor
//  Created:	16.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using Smart.Common;
//using Smart.Documents.Scopes;

namespace Smart.Workflow
{
	/// <summary>
	/// Assignment instance
	/// </summary>
	[Serializable]
	public class AssignmentInstance : ActivityInstance
	{
		public Assignment Definition;
		public ActionRuleInstanceList ActionRules;

		public DateTime Created;
		public TimeSpan Term;
		public DateTime DueDate;

		public int OriginatorId;
		public string OriginatorName;
		public string OriginatorEmail;

		public int AssigneeId;
		public string AssigneeName;
		public string AssigneeEmail;
		public SPPrincipalType AssigneeType;

		public bool AssigneeNotFound;

		public Guid TaskId;

		public SPContentTypeId TaskContentTypeId;

		/// <summary>
		/// Initializes a new instance of the <see cref="T:Smart.Workflow.AssignmentInstance"/> class.
		/// </summary>
		public AssignmentInstance(ProcessInstance parent, string name, int index, Assignment definition, IEnumerable<ActionRule> actionRules)
			: base(parent, name, index)
		{
			Definition = definition;

			ActionRules = new ActionRuleInstanceList(this, actionRules);
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="T:Smart.Workflow.AssignmentInstance"/> class.
		/// </summary>
		public AssignmentInstance(ProcessInstance parent, string name, int index, Assignment definition, IEnumerable<ActionRuleInstance> actionRules)
			: base(parent, name, index)
		{
			Definition = definition;

			ActionRules = new ActionRuleInstanceList(actionRules);

			foreach (var instance in ActionRules)
				instance.Parent = this;
		}

		/// <summary>
		/// Setup instance
		/// </summary>
		public virtual void Setup(IWorkflowService service)
		{
			var WorkflowProperties = service.WorkflowProperties;

			TaskId = Guid.NewGuid();

			OriginatorId = WorkflowProperties.OriginatorUser.ID;
			OriginatorName = WorkflowProperties.Originator;
			OriginatorEmail = WorkflowProperties.OriginatorEmail;

			var principal = WorkflowProperties.Web.GetPrincipal(Definition.PrincipalName);

			if (principal == null)
			{
				AssigneeId = OriginatorId;
				AssigneeName = OriginatorName;
				AssigneeEmail = OriginatorEmail;

				AssigneeType = SPPrincipalType.User;

				AssigneeNotFound = true;
			}
			else
			{
				AssigneeId = principal.ID;
				AssigneeName = principal.LoginName;
				AssigneeEmail = principal.GetEmails();

				if (principal is SPUser)
					AssigneeType = SPPrincipalType.User;
				else if (principal is SPGroup)
					AssigneeType = SPPrincipalType.SharePointGroup;
				else
					AssigneeType = SPPrincipalType.None;

				AssigneeNotFound = false;
			}

			Created = DateTime.Now;
			Term = Definition.Term.ParseXmlDuration(TimeSpan.Zero);
			throw new NotImplementedException();
			//DueDate =
			//	Term <= TimeSpan.Zero
			//		? DateTime.MinValue
			//		: WorkingScheduleContext.CalcEndDate(AssigneeId, Created, Term);

			var ctid = service.GetTaskContentTypeId(Definition.TaskType);

			if (!ctid.IsContentTypeId())
				ctid = Definition.TaskContentTypeId;

			if (!ctid.IsContentTypeId())
				ctid = SPBuiltInContentTypeId.WorkflowTask.ToString();

			TaskContentTypeId = new SPContentTypeId(ctid);
		}

		/// <summary>
		/// Create task properties from instance
		/// </summary>
		public virtual SPWorkflowTaskProperties GetTaskProperties()
		{
			var props =
				new SPWorkflowTaskProperties
					{
						AssignedTo = AssigneeName,
						Title = Definition.TaskTitle,
						Description = Definition.TaskDescription,
						SendEmailNotification = true
					};

			if (AssigneeNotFound)
			{
				var pi = SPUtility.ResolvePrincipal(SPH.GetWeb(), Definition.PrincipalName, SPPrincipalType.All, SPPrincipalSource.All, null, false);

				if (pi != null)
					props.OnBehalfEmail = pi.Email;

				props.OnBehalfReason = string.Format("AssigneeNotFound_OnBehalfReason".Localized(), Definition.PrincipalName, SPH.GetCurrentWebUrl());
			}

			props.ExtendedProperties["AllowDelegation"] = Definition.AllowDelegation;
			props.ExtendedProperties["AllowSuspending"] = Definition.AllowSuspending;

			return props;
		}

		/// <summary>
		/// Create task special permissions
		/// </summary>
		public virtual HybridDictionary GetTaskSpecialPermissions()
		{
			var permissions = new HybridDictionary();

			permissions[OriginatorName] = SPRoleType.Reader;
			permissions[AssigneeName] = SPRoleType.Contributor;

			return permissions;
		}

		/// <summary>
		/// Returns ContentTypeId
		/// </summary>
		public virtual SPContentTypeId GetTaskContentTypeId(SPList tasList)
		{
			if (tasList == null) throw new ArgumentNullException("tasList");

			return
				tasList.ContentTypes.BestMatch(TaskContentTypeId);
		}
	}
}